home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-08-25 | 25.4 KB | 1,113 lines |
-
- /*
- TransDisplay version 2.0 - TransSkel plug-in module supporting
- an arbitrary number of generic display windows with memory.
-
- TransSkel and TransDisplay are public domain, and are written by:
-
- Paul DuBois
- Wisconsin Regional Primate Research Center
- 1220 Capitol Court
- Madison, WI 53715-1299 USA
-
- UUCP: {harvard,rutgers,ucbvax}!uwvax!rhesus!dubois
- ARPA: dubois@primate.wisc.edu
-
- This version of TransDisplay written for LightspeedC. LightspeedC
- is a trademark of:
- THINK Technologies, Inc
- 420 Bedford Street Suite 350
- Lexington, MA 02173 USA
-
- History
- 08/25/86 Genesis. Beta version.
- 09/15/86 Changed to allow arbitrary number of windows. Changed
- version number to 1.0.
- 01/17/87 Changed version number to 1.01. The window type when a new
- window is created with NewDWindow is documentProc+8 now, so
- that the window will have a zoom box on a machine with 128K
- ROMS.
- 01/29/89 Version 2.0. Converted to work with TransSkel 2.0. Display
- window creation routines now check whether window and window
- handler creation succeeded and return nil if not. 2-byte and
- 4-byte integer types are typedef'ed to Integer and Longint to
- ease porting.
- */
-
-
- /*
- The following symbol controls the compile mode. If it is #define'd,
- TransDisplay allows only a single display window, and generates
- less code. If it is #undef'ed, TransDisplay allows an arbitrary
- number of display windows, but generates more code.
- */
-
- # undef singleDisplay
-
- # include <Controls.h> /* includes WindowMgr.h, QuickDraw.h, MacTypes.h */
- # include <TextEdit.h>
- #include <Memory.h>
- #include <Events.h>
- #include <Menus.h>
- #include <Memory.h>
- #include <Quickdraw.h>
- #include <Fonts.h>
- #include <Dialogs.h>
- #include <OSEvents.h>
- #include <ToolUtils.h>
- #include <Resources.h>
- #include "TransSkel.h"
- #include "TransDisplay.h"
-
- /*
- Display window types, constants, variables.
- */
-
-
- # define monaco 4
-
-
- /*
- Default values for display window characteristics
- */
-
- static Integer d_font = monaco; /* default font */
- static Integer d_size = 9; /* default pointsize */
- static Integer d_wrap = 0; /* default word wrap (on) */
- static Integer d_just = teJustLeft; /* default justification */
- static Longint d_maxText = 30000L; /* default max text allowed */
- static Longint d_flushAmt = 25000L; /* default autoflush amount */
- static ProcPtr d_activate = nil; /* default notification proc */
-
-
- /*
- Lowest allowable values for autoflush characteristics
- */
-
- # define d_loMaxText (100L)
- # define d_loFlushAmt (100L)
-
-
- # ifndef singleDisplay
-
- /*
- New(TypeName) returns handle to new object, for any TypeName.
- If there is insufficient memory, the result is nil.
- */
-
- # define New(x) (x **) NewHandle ((Size) sizeof (x))
-
-
- /*
- dwList points to a list of structures describing the known display
- windows.
-
- curDispWind is the current output window.
- If curDispWind = nil, output is currently turned off.
- */
-
-
- typedef struct DisplayInfo
- {
- WindowPtr dWind; /* display window */
- TEHandle dTE; /* window text */
- ControlHandle dScroll; /* window scroll bar */
- ProcPtr dActivate; /* notification procedure */
- Longint dMaxText; /* max text length */
- Longint dFlushAmt; /* amount to autoflush */
- struct DisplayInfo **dNext; /* next window structure */
- } DisplayInfo, *DIPtr, **DIHandle;
-
-
- static DIHandle dwList = nil;
-
- # endif
-
- /*
- Variables pertaining to the display window being operated on
- (updated, resized, etc.). This window is not necessarily the
- same as curDispWind! These variables are synced to the window
- with SyncGlobals.
- */
-
- # ifndef singleDisplay
- static DIHandle dispInfo; /* info structure */
- # endif
-
- static DrawGrowBox(void);
- static DIHandle GetDInfo(WindowPtr theWind);
- static SyncGlobals(WindowPtr theWind);
- static CalcEditRect(Rect *r);
- static CalcScrollRect(Rect *r);
- static LinesOffTop(void);
- static HiliteScroll(void);
- static ScrollText(Integer lDelta);
- static pascal void TrackScroll(ControlHandle theScroll, Integer partCode);
- static OverhaulDisplay(void);
- static Activate(Boolean isActive);
- static Update(Boolean resized);
- static Mouse(Point thePt, Longint t, Integer mods);
- static Clobber(void);
- static SetupDWindow(void);
- static HexByte(Integer value);
-
- static WindowPtr dispWind = nil; /* the window */
- static TEHandle dispTE; /* window text */
- static ControlHandle dispScroll; /* the scroll bar */
- static ProcPtr dActivate; /* notification procedure */
- static Longint dMaxText; /* max text allowed */
- static Longint dFlushAmt; /* amount to flush */
-
-
- /*
- curDispWind is the current output window.
- If curDispWind = nil, output is turned off.
- */
-
- static WindowPtr curDispWind = nil;
-
-
- /* -------------------------------------------------------------------- */
- /* Miscellaneous Internal (private) Routines */
- /* -------------------------------------------------------------------- */
-
-
- /*
- Draw grow box of dispWind in lower right hand corner
- */
-
-
- static DrawGrowBox (void)
- {
- register RgnHandle oldClip;
- Rect r;
-
- r = dispWind->portRect;
- r.left = r.right - 15; /* draw only in corner */
- r.top = r.bottom - 15;
- oldClip = NewRgn ();
- GetClip (oldClip);
- ClipRect (&r);
- DrawGrowIcon (dispWind);
- SetClip (oldClip);
- DisposeRgn (oldClip);
- }
-
-
-
- /* -------------------------------------------------------------------- */
- /* Lowest-level Internal (Private) Display Window Routines */
- /* -------------------------------------------------------------------- */
-
-
- # ifndef singleDisplay
-
- /*
- Get display window info associated with window.
- Return nil if window isn't a known display window.
- */
-
- static DIHandle GetDInfo (WindowPtr theWind)
- {
- register DIHandle h;
-
- for (h = dwList; h != nil; h = (**h).dNext)
- {
- if ((**h).dWind == theWind)
- return (h);
- }
- return (nil);
- }
-
- # endif
-
- # ifdef singleDisplay
- # define SyncGlobals(x) ; /* make it a nop */
- # else
-
- /*
- Synchronize globals to a display window. theWind must be a legal
- display window, with one exception: if theWind is nil, the
- variables are synced to the current port. That is safe (and
- correct) because:
- (i) nil is only passed by display window handler procedures,
- which are only called by TransSkel for display window
- events.
- (ii) For those handler procs that pass nil, TransSkel either sets
- the port to the window before calling the proc (update, clobber,
- idle procs), or the window is frontmost, and so will be the
- current port anyway (mouse proc).
- Hence, use of the current port under these circumstances
- always produces a legal display window.
-
- SyncGlobals is not used in single display mode, because the
- globals are all set by SetupDWindow and do not change thereafter.
- */
-
- static SyncGlobals (WindowPtr theWind)
- {
- register DIPtr dp;
-
- if (theWind == nil) /* use current window */
- GetPort (&theWind);
-
- dispWind = theWind;
- dispInfo = GetDInfo (dispWind);
- dp = *dispInfo;
- dispScroll = (*dp).dScroll;
- dispTE = (*dp).dTE;
- dActivate = (*dp).dActivate;
- dMaxText = (*dp).dMaxText;
- dFlushAmt = (*dp).dFlushAmt;
- }
-
- # endif
-
-
- /*
- Calculate the dimensions of the editing rectangle for
- dispWind (which must be set properly and is assumed to be
- the current port). (The viewRect and destRect are the
- same size.) Assumes the port, text font and text size are all
- set properly. The viewRect is sized so that an integral
- number of lines can be displayed in it, i.e., so that a
- partial line never shows at the bottom.
- */
-
- static CalcEditRect (Rect *r)
- {
- FontInfo f;
- register Integer lineHeight;
-
- GetFontInfo (&f);
- lineHeight = f.ascent + f.descent + f.leading;
- *r = dispWind->portRect;
- r->left += 4;
- r->right -= 17; /* leave room for scroll bar + 2 */
- r->top += 2;
- r->bottom = r->top + ((r->bottom - r->top - 2) / lineHeight) * lineHeight;
- }
-
-
- /*
- Calculate the dimensions of the scroll bar rectangle for the
- window. Make sure that the edges overlap the window frame and
- the grow box.
- */
-
- static CalcScrollRect (Rect *r)
- {
- *r = dispWind->portRect;
- ++r->right;
- --r->top;
- r->left = r->right - 16;
- r->bottom -= 14;
- }
-
-
- /*
- Calculate the number of lines currently scrolled off
- the top.
- */
-
- static LinesOffTop (void)
- {
- register TEPtr ePtr;
-
- ePtr = *dispTE;
- return (((*ePtr).viewRect.top - (*ePtr).destRect.top)
- / (*ePtr).lineHeight);
- }
-
-
- /*
- Highlight the scroll bar properly. This means that it's not
- made active if the window itself isn't active, even if
- there's enough text to fill the window.
- */
-
- static HiliteScroll (void)
- {
- HiliteControl (dispScroll, dispWind == FrontWindow () &&
- GetCtlMax (dispScroll) > 0 ? 0 : 255);
- }
-
-
- /*
- Scroll to the correct position. lDelta is the
- amount to CHANGE the current scroll setting by.
- Positive scrolls the text up, negative down.
- */
-
- static ScrollText (Integer lDelta)
- {
- register Integer lHeight;
- register Integer newLine;
- register Integer topLine;
-
- lHeight = (**dispTE).lineHeight;
- topLine = LinesOffTop ();
- newLine = topLine + lDelta;
- if (newLine < 0)
- newLine = 0;
- if (newLine > GetCtlMax (dispScroll))
- newLine = GetCtlMax (dispScroll);
- SetCtlValue (dispScroll, newLine);
- TEScroll (0, (topLine - newLine ) * lHeight, dispTE);
- }
-
-
- /*
- Filter proc for tracking mousedown in scroll bar. The code for
- the part originally hit is stored in the control's reference
- value by Mouse () before calling this.
-
- Scroll by one line if the mouse is in an arrow. Scroll by a half
- window's worth of lines if the mouse is in a page region.
- */
-
- static pascal void TrackScroll (ControlHandle theScroll, Integer partCode)
- {
- register Integer lDelta;
- register Integer halfPage;
-
- if (partCode == GetCRefCon (theScroll)) /* still in same part? */
- {
- halfPage = (((**dispTE).viewRect.bottom - (**dispTE).viewRect.top)
- / (**dispTE).lineHeight) / 2;
- if (halfPage == 0)
- ++halfPage;
- switch (partCode)
- {
- case inUpButton: lDelta = -1; break;
- case inDownButton: lDelta = 1; break;
- case inPageUp: lDelta = -halfPage; break;
- case inPageDown: lDelta = halfPage; break;
- }
- ScrollText (lDelta);
- }
- }
-
-
- /*
- Adjust the text in the text record and the scroll bar. This is
- called for major catastrophes, such as resizing the window, or
- changing the word wrap style. It makes sure the view and
- destination rectangles are sized properly, and that the bottom
- line of text never scrolls up past the bottom line of the
- window, if there's enough to fill the window, and that the
- scroll bar max and current values are set properly.
-
- Resizing the dest rect just means resetting the right edge
- (the top is NOT reset), since text might be scrolled off the
- top (i.e., destRect.top != 0).
- */
-
- static OverhaulDisplay (void)
- {
- Rect r;
- register Integer nLines; /* # of lines in TERec */
- register Integer visLines; /* # of lines displayable in window */
- register Integer topLines; /* # of lines currently scrolled off top */
- register Integer scrollLines; /* # of lines to scroll down */
- register Integer lHeight;
-
- CalcEditRect (&r);
- (**dispTE).destRect.right = r.right;
- (**dispTE).viewRect = r;
- TECalText (dispTE); /* recalc line starts */
- /*r = (**dispTE).viewRect;*/ /* ?? */
- lHeight = (**dispTE).lineHeight;
- nLines = (**dispTE).nLines;
- visLines = (r.bottom - r.top) / lHeight;
- topLines = LinesOffTop ();
-
- /*
- If the text doesn't fill the window (visLines > nLines - topLines),
- pull the text down if possible (if topLines > 0). Make sure not
- to try to scroll down by more lines than are hidden off the top.
- */
- scrollLines = visLines - (nLines - topLines);
- if (scrollLines > 0 && topLines > 0)
- {
- if (scrollLines > topLines)
- scrollLines = topLines;
- TEScroll (0, scrollLines * lHeight, dispTE);
- topLines -= scrollLines;
- }
- TEUpdate (&r, dispTE);
-
- SetCtlMax (dispScroll, nLines - visLines < 0 ? 0 : nLines - visLines);
- SetCtlValue (dispScroll, topLines);
- HiliteScroll ();
- }
-
-
- /* ---------------------------------------------------------------- */
- /* Window Handler Routines */
- /* ---------------------------------------------------------------- */
-
-
- /*
- When the window comes active, highlight the scroll bar appropriately.
- When the window is deactivated, un-highlight the scroll bar.
- Redraw the grow box.
-
- Notify the host as appropriate.
-
- Note that clicking close box hides the window, which generates a
- deactivate event, so there is no need for a close notifier.
- */
-
- static Activate (Boolean isActive)
- {
- SyncGlobals (nil); /* sync to current port */
- DrawGrowBox ();
- HiliteScroll ();
-
- if (dActivate != nil)
- ((void (*)(Boolean)) dActivate) (isActive);
- }
-
-
- /*
- Update window. The update event might be in response to a
- window resizing. If so, move and resize the scroll bar,
- and recalculate the text display.
-
- The ValidRect call is done because the HideControl adds the
- control bounds box to the update region - which would generate
- another update event! Since everything is redrawn below anyway,
- the ValidRect is used to cancel the update.
- */
-
- static Update (Boolean resized)
- {
- Rect r;
-
- SyncGlobals (nil); /* sync to current port */
- r = dispWind->portRect;
- EraseRect (&r);
- if (resized)
- {
- HideControl (dispScroll);
- r = (**dispScroll).contrlRect;
- ValidRect (&r);
- CalcScrollRect (&r);
- SizeControl (dispScroll, 16, r.bottom - r.top);
- MoveControl (dispScroll, r.left, r.top);
- OverhaulDisplay ();
- ShowControl (dispScroll);
- }
- else
- {
- r = (**dispTE).viewRect;
- TEUpdate (&r, dispTE); /* redraw text display */
- }
-
- DrawGrowBox ();
- DrawControls (dispWind); /* redraw scroll bar */
- }
-
-
- /*
- Handle mouse clicks in window
- */
-
- static Mouse (Point thePt, Longint t, Integer mods)
- {
- register Integer thePart;
- register Integer oldCtlValue;
-
- SyncGlobals (nil); /* sync to current port */
-
- if ((thePart = TestControl (dispScroll, thePt)) == inThumb)
- {
- oldCtlValue = GetCtlValue (dispScroll);
- if (TrackControl (dispScroll, thePt, nil) == inThumb)
- ScrollText (GetCtlValue (dispScroll) - oldCtlValue);
- }
- else if (thePart != 0)
- {
- SetCRefCon (dispScroll, (Longint) thePart);
- (void) TrackControl (dispScroll, thePt, &TrackScroll);
- }
- }
-
-
-
- /*
- Remove the display window from the list, and dispose of it.
- Since the clobber procedure is never called except for real display
- windows, and since the list must therefore be non-empty, it is
- not necessary to check the legality of the window or that the
- window's in the list.
-
- Must do SetDWindow (nil) to turn output off, if the window being
- clobbered is the current output window.
- */
-
- static Clobber (void)
- {
- # ifndef singleDisplay
- register DIHandle h, h2;
- # endif
-
- SyncGlobals (nil); /* sync to current port */
-
- if (dispWind == curDispWind)
- SetDWindow (nil);
-
- # ifndef singleDisplay
-
- if ((**dwList).dWind == dispWind) /* is it the first window in list? */
- {
- h2 = dwList;
- dwList = (**dwList).dNext;
- }
- else
- {
- for (h = dwList; h != nil; h = h2)
- {
- h2 = (**h).dNext;
- if ((**h2).dWind == dispWind) /* found it */
- {
- (**h).dNext = (**h2).dNext;
- break;
- }
- }
- }
- DisposHandle ((Handle)h2); /* get rid of information structure */
-
- # endif
-
- TEDispose (dispTE); /* toss text record */
- DisposeWindow (dispWind); /* toss window and scroll bar */
- dispWind = nil;
- }
-
-
- /* ---------------------------------------------------------------- */
- /* Control Routines */
- /* ---------------------------------------------------------------- */
-
-
- /*
- Test whether a window is a legal display window or not
- */
-
- Boolean IsDWindow (WindowPtr theWind)
- {
-
- # ifdef singleDisplay
- return (theWind == dispWind && dispWind != nil);
- # else
- return (GetDInfo (theWind) != nil);
- # endif
- }
-
-
- /*
- Return handle to display window's text record
- */
-
- TEHandle GetDWindowTE (WindowPtr theWind)
- {
-
- # ifndef singleDisplay
- register DIHandle dInfo;
- return (GetDInfo (theWind) == nil ? nil : (**dInfo).dTE);
- # else
- return (IsDWindow (theWind) ? dispTE : nil);
- # endif
- }
-
-
- /*
- Change the text display characteristics of a display window
- and redisplay it. As a side effect, this always scrolls to the
- home position.
- */
-
- SetDWindowStyle (WindowPtr theWind, Integer font, Integer size, Integer wrap, Integer just)
- {
- GrafPtr savePort;
- FontInfo f;
- register TEHandle te;
- Rect r;
-
- if (theWind == nil) /* reset window creation defaults */
- {
- d_font = font;
- d_size = size;
- d_wrap = wrap;
- d_just = just;
- return;
- }
-
- if (IsDWindow (theWind))
- {
- GetPort (&savePort);
- SyncGlobals (theWind);
- SetPort (dispWind);
- te = dispTE;
- r = (**te).viewRect;
- EraseRect (&r);
- r = (**te).destRect; /* scroll home without redrawing */
- OffsetRect (&r, 0, 2 - r.top);
- (**te).destRect = r;
-
- (**te).crOnly = wrap; /* set word wrap */
- TESetJust (just, te); /* set justification */
-
- TextFont (font); /* set the font and point size */
- TextSize (size); /* of text record (this is the */
- GetFontInfo (&f); /* hard part) */
- (**te).lineHeight = f.ascent + f.descent + f.leading;
- (**te).fontAscent = f.ascent;
- (**te).txFont = font;
- (**te).txSize = size;
-
- OverhaulDisplay ();
- SetPort (savePort);
- }
- }
-
-
- /*
- Scroll the text in the window so that line lineNum is at the top.
- First line is line zero.
- */
-
- SetDWindowPos (WindowPtr theWind, Integer lineNum)
- {
- GrafPtr savePort;
-
- if (IsDWindow (theWind))
- {
- GetPort (&savePort);
- SyncGlobals (theWind);
- SetPort (dispWind);
- ScrollText (lineNum - GetCtlValue (dispScroll));
- SetPort (savePort);
- }
- }
-
-
- /*
- Set display window activate notification procedure.
- Pass nil to disable it.
- */
-
- SetDWindowNotify (WindowPtr theWind, ProcPtr p)
- {
- # ifndef singleDisplay
- register DIHandle dInfo;
- # endif
-
- if (theWind == nil) /* reset window creation default */
- {
- d_activate = p;
- return;
- }
-
- # ifdef singleDisplay
-
- if (IsDWindow (theWind))
- dActivate = p;
-
- # else
-
- if ((dInfo = GetDInfo (theWind)) != nil)
- {
- (**dInfo).dActivate = p;
- }
-
- # endif
- }
-
-
- /*
- Set display window autoflush characteristics
- */
-
- SetDWindowFlush (WindowPtr theWind, Longint maxText, Longint flushAmt)
- {
- # ifndef singleDisplay
- register DIHandle dInfo;
- # endif
-
- if (maxText > 32767L)
- maxText = 32767L;
- if (maxText < d_loMaxText)
- maxText = d_loMaxText;
- if (flushAmt < d_loFlushAmt)
- flushAmt = d_loFlushAmt;
-
- if (theWind == nil) /* reset window creation defaults */
- {
- d_maxText = maxText;
- d_flushAmt = flushAmt;
- return;
- }
-
- # ifdef singleDisplay
-
- if (IsDWindow (theWind))
- {
-
- dMaxText = maxText;
- dFlushAmt = flushAmt;
- }
-
- # else
-
- if ((dInfo = GetDInfo (theWind)) != nil)
- {
- (**dInfo).dMaxText = maxText;
- (**dInfo).dFlushAmt = flushAmt;
- }
-
- # endif
- }
-
-
- /*
- Set which display window is to be used for output. If theWind
- is nil, output is turned off. If theWind is not a legal display
- window, nothing is done.
- */
-
- SetDWindow (WindowPtr theWind)
- {
- if (theWind == nil || IsDWindow (theWind))
- {
- curDispWind = theWind;
- }
- }
-
-
- /*
- Get the WindowPtr of the current output display window. If
- output is turned off, this will be nil.
- */
-
- GetDWindow (WindowPtr *theWind)
- {
- *theWind = curDispWind;
- }
-
-
- /*
- Flush text from the window and readjust the display.
- */
-
- FlushDWindow (WindowPtr theWind, Longint byteCount)
- {
- if (IsDWindow (theWind))
- {
- SyncGlobals (theWind);
- TESetSelect (0L, byteCount, dispTE); /* select text */
- TEDelete (dispTE); /* clobber it */
- OverhaulDisplay ();
- }
- }
-
-
- /*
- Create and initialize a display window and the associated data
- structures, and return the window pointer. Install window in
- list of display windows.
- */
-
- static SetupDWindow (void)
- {
- Rect r;
- GrafPtr savePort;
-
- # ifndef singleDisplay
- register DIHandle dInfo;
- # endif
-
-
- GetPort (&savePort);
- if (SkelWindow (dispWind, /* the window */
- Mouse, /* mouse click handler */
- nil, /* key clicks are ignored */
- Update, /* window updating procedure */
- Activate, /* window activate/deactivate procedure */
- nil, /* TransSkel hides window if no close proc */
- /* (generates deactivate event) */
- Clobber, /* window disposal procedure */
- nil, /* no idle proc */
- false) == 0) /* irrelevant since no idle proc */
- {
- SetPort (savePort);
- return (0);
- }
-
- /*
- Build the scroll bar. Make sure the borders overlap the
- window frame and the frame of the grow box.
- */
-
- CalcScrollRect (&r);
- dispScroll = NewControl (dispWind, &r, "\p", true, 0, 0, 0,
- scrollBarProc, 0L);
-
- /*
- Create the TE record used for text display. Use defaults for
- display characteristics. Setting window style overhauls
- display, so can cancel and update event pending for the window.
- */
-
- CalcEditRect (&r);
- dispTE = TENew (&r, &r);
-
- # ifndef singleDisplay
-
- /*
- Get new information structure, attach to list of known display
- windows.
- */
- dInfo = New (DisplayInfo);
- (**dInfo).dNext = dwList;
- dwList = dInfo;
- (**dInfo).dWind = dispWind;
- (**dInfo).dScroll = dispScroll;
- (**dInfo).dTE = dispTE;
-
- # endif
-
- SetDWindowNotify (dispWind, d_activate);
- SetDWindowFlush (dispWind, d_maxText, d_flushAmt);
- SetDWindowStyle (dispWind, d_font, d_size, d_wrap, d_just);
-
- /*
- Make window current display output window
- */
-
- SetDWindow (dispWind);
- SetPort (savePort);
- return (1);
- }
-
-
- /*
- Create and initialize a display window and the associated data
- structures, and return the window pointer. Install window in
- list of display windows. In single-window mode, disallow
- creation of a new window if one already exists.
-
- The parameters are similar to those for NewWindow. See Inside
- Macintosh.
- */
-
- WindowPtr NewDWindow (Rect *bounds, StringPtr title, Boolean visible, WindowPtr behind, Boolean goAway, Longint refCon)
- {
-
- # ifdef singleDisplay
-
- if (dispWind != nil)
- return (nil);
-
- # endif
-
- if ((dispWind = NewWindow (nil,
- bounds,
- title,
- visible,
- documentProc + 8,
- behind,
- goAway,
- refCon)) != nil)
- {
- if (SetupDWindow ())
- return (dispWind);
- DisposeWindow (dispWind);
- }
- return (nil);
- }
-
-
- /*
- Create and initialize a display window (using a resource) and
- the associated data structures, and return the window pointer.
- Install window in list of display windows. In single-window
- mode, disallow creation of a new window if one already exists.
-
- The parameters are similar to those for GetNewWindow. See Inside
- Macintosh.
- */
-
- WindowPtr GetNewDWindow (Integer resourceNum, WindowPtr behind)
- {
-
- # ifdef singleDisplay
-
- if (dispWind != nil)
- return (nil);
-
- # endif
-
- if ((dispWind = GetNewWindow (resourceNum, nil, behind)) != nil)
- {
- if (SetupDWindow ())
- return (dispWind);
- DisposeWindow (dispWind);
- }
- return (nil);
- }
-
-
-
-
- /* ------------------------------------------------------------ */
- /* Output Routines */
- /* ------------------------------------------------------------ */
-
-
- /*
- Write text to display area if output is on (curDispWind != nil).
- DisplayText is the fundamental output routine. All other
- output calls map (eventually) to it.
-
- First check whether the insertion will cause overflow and flush
- out some stuff if so. Insert new text at the end, then test
- whether lines must be scrolled to get the new stuff to show up.
- If yes, then do the scroll. Set values of scroll bar properly
- and highlight as appropriate.
-
- The current port is preserved. Since all output calls end up
- here, it's the only output routine that has to save the port
- and check whether output is on.
- */
-
- DisplayText (Ptr theText, Longint len)
- {
- register Integer nLines; /* # of lines in TERec */
- register Integer dispLines; /* # of lines displayable in window */
- register Integer topLines; /* # of lines currently scrolled off top */
- register Integer scrollLines; /* # of lines to scroll up */
- register Integer lHeight;
- Rect r;
- GrafPtr savePort;
- register TEHandle dTE;
-
- if (curDispWind == nil)
- return;
-
- GetPort (&savePort);
- SetPort (curDispWind);
- SyncGlobals (curDispWind);
- dTE = dispTE;
-
- if ((**dTE).teLength + len > dMaxText) /* check overflow */
- {
- FlushDWindow (dispWind, dFlushAmt);
- DisplayString ("\p\r(autoflush occurred)\r");
- }
-
- lHeight = (**dTE).lineHeight;
- TESetSelect (32767L, 32767L, dTE); /* set to insert at end */
- TEInsert (theText, len, dTE);
- r = (**dTE).viewRect;
- nLines = (**dTE).nLines;
- dispLines = (r.bottom - r.top) / lHeight;
- topLines = LinesOffTop ();
- scrollLines = nLines - (topLines + dispLines);
- if (scrollLines > 0) /* must scroll up */
- TEScroll (0, -lHeight * scrollLines, dTE); /* scroll up */
- topLines = nLines - dispLines;
- if (topLines >= 0 && GetCtlMax (dispScroll) != topLines)
- {
- SetCtlMax (dispScroll, topLines);
- SetCtlValue (dispScroll, topLines);
- }
- HiliteScroll ();
- SetPort (savePort);
- }
-
-
- /*
- Derived output routines:
-
- DisplayString Write (Pascal) string
-
- DisplayLong Write value of long integer
- DisplayInt Write value of integer
- DisplayChar Write character
-
- DisplayHexLong Write value of long integer in hex (8 digits)
- DisplayHexInt Write value of integer in hex (4 digits)
- DisplayHexChar Write value of character in hex (2 digit)
-
- DisplayBoolean Write boolean value
- DisplayLn Write carriage return
- */
-
- DisplayString (StringPtr theStr)
- {
- DisplayText ((void *)(theStr+1), (Longint) theStr[0]);
- }
-
-
- DisplayLong (Longint l)
- {
- Str255 s;
-
- NumToString (l, s);
- DisplayString (s);
- }
-
-
- DisplayInt (Integer i)
- {
- DisplayLong ((Longint) i);
- }
-
-
- DisplayChar (char c)
- {
- DisplayText (&c, 1L);
- }
-
-
- DisplayLn (void)
- {
- DisplayChar ('\r');
- }
-
-
- DisplayBoolean (Boolean b)
- {
- DisplayString (b ? "\ptrue" : "\pfalse");
- }
-
-
- static HexByte (Integer value)
- {
- DisplayChar ((char) (value + (value < 10 ? '0' : 'a' - 10)));
- }
-
-
- DisplayHexChar (char c)
- {
- HexByte ((Integer) (c >> 4) & 0x0f);
- HexByte ((Integer) c & 0x0f);
- }
-
-
- DisplayHexInt (Integer i)
- {
- DisplayHexChar ((char) ((i >> 8) & 0xff));
- DisplayHexChar ((char) (i & 0xff));
- }
-
-
- DisplayHexLong (Longint l)
- {
- DisplayHexInt ((Integer) (l >> 16) & 0xffff);
- DisplayHexInt ((Integer) l & 0xffff);
- }
-